package org.proteored.miapeapi.xml.pride.adapter;

import java.util.List;
import java.util.Set;

import org.apache.log4j.Logger;
import org.proteored.miapeapi.cv.Accession;
import org.proteored.miapeapi.cv.ControlVocabularyManager;
import org.proteored.miapeapi.cv.ControlVocabularyTerm;
import org.proteored.miapeapi.cv.PSIMassSpectrometryOntology;
import org.proteored.miapeapi.cv.ms.AcquisitionParameters;
import org.proteored.miapeapi.cv.ms.AcquisitionSoftware;
import org.proteored.miapeapi.cv.ms.CollisionPressure;
import org.proteored.miapeapi.cv.ms.DelayedExtraction;
import org.proteored.miapeapi.cv.ms.DissociationMethod;
import org.proteored.miapeapi.cv.ms.GasType;
import org.proteored.miapeapi.cv.ms.InstrumentCfg;
import org.proteored.miapeapi.cv.ms.InstrumentCustomization;
import org.proteored.miapeapi.cv.ms.InstrumentModel;
import org.proteored.miapeapi.cv.ms.InstrumentVendor;
import org.proteored.miapeapi.cv.ms.IonSourceName;
import org.proteored.miapeapi.cv.ms.LaserAttribute;
import org.proteored.miapeapi.cv.ms.LaserType;
import org.proteored.miapeapi.cv.ms.MSFileType;
import org.proteored.miapeapi.cv.ms.MaldiDissociationMethod;
import org.proteored.miapeapi.cv.ms.MassAnalyzerType;
import org.proteored.miapeapi.cv.ms.MatrixComposition;
import org.proteored.miapeapi.cv.ms.ReflectronState;
import org.proteored.miapeapi.cv.ms.SamplePlateType;
import org.proteored.miapeapi.cv.ms.SoftwareManufacturer;
import org.proteored.miapeapi.cv.ms.SourceInterface;
import org.proteored.miapeapi.cv.ms.SourceSprayer;
import org.proteored.miapeapi.cv.ms.SpectrometerName;
import org.proteored.miapeapi.cv.ms.SupplyType;
import org.proteored.miapeapi.cv.ms.TargetList;
import org.proteored.miapeapi.interfaces.Adapter;
import org.proteored.miapeapi.interfaces.Equipment;
import org.proteored.miapeapi.interfaces.ms.Acquisition;
import org.proteored.miapeapi.interfaces.ms.ActivationDissociation;
import org.proteored.miapeapi.interfaces.ms.Analyser;
import org.proteored.miapeapi.interfaces.ms.Esi;
import org.proteored.miapeapi.interfaces.ms.InstrumentConfiguration;
import org.proteored.miapeapi.interfaces.ms.Maldi;
import org.proteored.miapeapi.interfaces.ms.MiapeMSDocument;
import org.proteored.miapeapi.interfaces.ms.Spectrometer;
import org.proteored.miapeapi.xml.pride.autogenerated.InstrumentDescriptionType;
import org.proteored.miapeapi.xml.pride.autogenerated.InstrumentDescriptionType.AnalyzerList;
import org.proteored.miapeapi.xml.pride.autogenerated.ObjectFactory;
import org.proteored.miapeapi.xml.pride.autogenerated.ParamType;
import org.proteored.miapeapi.xml.pride.autogenerated.UserParamType;
import org.proteored.miapeapi.xml.pride.util.PrideControlVocabularyXmlFactory;

public class InstrumentDescriptionAdapter implements
		Adapter<InstrumentDescriptionType> {
	private static Logger log = Logger.getLogger("log4j.logger.org.proteored");
	private final ObjectFactory factory;
	private final ControlVocabularyManager cvManager;
	private final MiapeMSDocument miapeMS;
	private final PrideControlVocabularyXmlFactory prideCvUtil;

	public InstrumentDescriptionAdapter(ObjectFactory factory,
			ControlVocabularyManager cvManager, MiapeMSDocument miapeMS) {
		this.factory = factory;
		this.cvManager = cvManager;
		this.miapeMS = miapeMS;
		prideCvUtil = new PrideControlVocabularyXmlFactory(factory, cvManager);
	}

	@Override
	public InstrumentDescriptionType adapt() {
		String spectrometerName = "Unknown";
		ParamType prideSource = null;
		AnalyzerList prideAnalyzerList = null;

		// create unknown detector
		ParamType prideDetectors = factory.createParamType();
		prideCvUtil.addUserParamToParamType(prideDetectors, "detector",
				"not provided / not MIAPE compliant");

		ParamType prideAdditional = factory.createParamType();

		log.info("adding instrument");
		InstrumentDescriptionType prideInstrument = factory
				.createInstrumentDescriptionType();

		if (miapeMS != null) {
			Set<Spectrometer> miapeSpectrometers = miapeMS.getSpectrometers();
			if (miapeSpectrometers != null && !miapeSpectrometers.isEmpty()) {
				Spectrometer spectrometer = miapeSpectrometers.iterator()
						.next();
				spectrometerName = spectrometer.getName();
				// store as CV Param if possible
				final ControlVocabularyTerm spectrometerCVTerm = SpectrometerName
						.getInstance(cvManager).getCVTermByPreferredName(
								spectrometerName);
				if (spectrometerCVTerm != null) {
					prideCvUtil.addCvParamToParamType(prideAdditional,
							spectrometerCVTerm.getTermAccession(),
							spectrometerCVTerm.getPreferredName(), null,
							spectrometerCVTerm.getCVRef());
				}
				if (spectrometerName.equals("Spectrometer"))
					spectrometerName = "NA";
				ControlVocabularyTerm instrumentConfigurationTerm = InstrumentCfg
						.getInstrumentConfigurationTerm();
				if (spectrometer.getDescription() != null
						&& !spectrometer.getDescription().equals(""))
					prideCvUtil.addUserParamToParamType(prideAdditional,
							PrideControlVocabularyXmlFactory.DESCRIPTION,
							spectrometer.getDescription());
				if (spectrometer.getComments() != null
						&& !spectrometer.getComments().equals(""))
					prideCvUtil.addUserParamToParamType(prideAdditional,
							PrideControlVocabularyXmlFactory.COMMENTS,
							spectrometer.getComments());
				if (spectrometer.getCustomizations() != null
						&& !spectrometer.getCustomizations().equals("")) {
					ControlVocabularyTerm customizationTerm = InstrumentCustomization
							.getInstance(cvManager)
							.getCVTermByAccession(
									InstrumentCustomization.INSTRUMENT_CUSTOMIZATION_ACC);

					prideCvUtil.addCvParamToParamType(prideAdditional,
							customizationTerm.getTermAccession(),
							customizationTerm.getPreferredName(),
							spectrometer.getCustomizations(),
							customizationTerm.getCVRef());
				}
				final ControlVocabularyTerm instrumentModelTerm = InstrumentModel
						.getInstrumentModelTerm(cvManager);
				if (spectrometer.getModel() != null
						&& !spectrometer.getModel().equals(""))
					prideCvUtil.addCvParamToParamType(prideAdditional,
							instrumentModelTerm.getTermAccession(),
							instrumentModelTerm.getPreferredName(),
							spectrometer.getModel(),
							instrumentModelTerm.getCVRef());
				ControlVocabularyTerm instumentVendorTerm = InstrumentVendor
						.getInstrumentVendorTerm();
				if (spectrometer.getManufacturer() != null
						&& !spectrometer.getManufacturer().equals(""))
					prideCvUtil.addCvParamToParamType(prideAdditional,
							instumentVendorTerm.getTermAccession(),
							instumentVendorTerm.getPreferredName(),
							spectrometer.getManufacturer(),
							instumentVendorTerm.getCVRef());
				if (spectrometer.getCatalogNumber() != null
						&& !spectrometer.getCatalogNumber().equals(""))
					prideCvUtil.addUserParamToParamType(prideAdditional,
							PrideControlVocabularyXmlFactory.CATALOG_NUMBER,
							spectrometer.getCatalogNumber());
				if (spectrometer.getParameters() != null
						&& !spectrometer.getParameters().equals(""))
					prideCvUtil.addCvParamToParamType(prideAdditional,
							instrumentConfigurationTerm.getTermAccession(),
							instrumentConfigurationTerm.getPreferredName(),
							spectrometer.getParameters(),
							instrumentConfigurationTerm.getCVRef());
				if (spectrometer.getUri() != null
						&& !spectrometer.getUri().equals(""))
					prideCvUtil.addUserParamToParamType(prideAdditional,
							PrideControlVocabularyXmlFactory.URI,
							spectrometer.getUri());
				if (spectrometer.getVersion() != null
						&& !spectrometer.getVersion().equals(""))
					prideCvUtil.addUserParamToParamType(prideAdditional,
							PrideControlVocabularyXmlFactory.VERSION,
							spectrometer.getVersion());
			}

			List<InstrumentConfiguration> instrumentConfigurations = miapeMS
					.getInstrumentConfigurations();
			if (instrumentConfigurations != null) {
				for (InstrumentConfiguration instrumentConfiguration : instrumentConfigurations) {
					List<Esi> miapeESIS = instrumentConfiguration.getEsis();
					List<Maldi> maldis = instrumentConfiguration.getMaldis();
					if ((miapeESIS != null && !miapeESIS.isEmpty())
							|| (maldis != null && !maldis.isEmpty())) {
						prideSource = createSource(miapeESIS, maldis);
					} else {
						prideSource = createSource(null, null);
					}
					List<Analyser> miapeAnalyzers = instrumentConfiguration
							.getAnalyzers();
					Set<ActivationDissociation> collisionCells = instrumentConfiguration
							.getActivationDissociations();
					// Set<IonOptic> ionOptics =
					// instrumentConfiguration.getIonOptics();
					// if ((miapeAnalyzers != null && !miapeAnalyzers.isEmpty())
					// || (collisionCells != null && !collisionCells.isEmpty())
					// || (ionOptics != null && !ionOptics.isEmpty())) {
					// prideAnalyzerList = createAnalyzers(miapeAnalyzers,
					// collisionCells,
					// ionOptics);
					// } else {
					// prideAnalyzerList = createAnalyzers(null, null, null);
					// }
					if ((miapeAnalyzers != null && !miapeAnalyzers.isEmpty())
							|| (collisionCells != null && !collisionCells
									.isEmpty())) {
						prideAnalyzerList = createAnalyzers(miapeAnalyzers,
								collisionCells);
					} else {
						prideAnalyzerList = createAnalyzers(null, null);
					}
				}
			} else {
				prideSource = createSource(null, null);
				prideAnalyzerList = createAnalyzers(null, null);
			}

			Set<Acquisition> acquisitions = miapeMS.getAcquisitions();
			if (acquisitions != null && !acquisitions.isEmpty()) {
				// name
				Acquisition acquisition = miapeMS.getAcquisitions().iterator()
						.next();
				String name = acquisition.getName();
				if (name != null && !"".equals(name)) {
					ControlVocabularyTerm acquisitionSoftwareTerm = AcquisitionSoftware
							.getInstance(cvManager)
							.getCVTermByAccession(
									AcquisitionSoftware.ACQUISITION_SOFTWARE_ACC);
					if (acquisitionSoftwareTerm != null) {
						prideCvUtil.addCvParamToParamType(prideAdditional,
								acquisitionSoftwareTerm.getTermAccession(),
								acquisitionSoftwareTerm.getPreferredName(),
								name, acquisitionSoftwareTerm.getCVRef());
					} else {
						prideCvUtil.addCvParamOrUserParamToParamType(
								prideAdditional, "acquisition software", name,
								AcquisitionSoftware.getInstance(cvManager));
					}
				}
				// parameters
				String acquisitionParameters = acquisition.getParameters();
				if (acquisitionParameters != null
						&& !"".equals(acquisitionParameters)) {
					ControlVocabularyTerm acquisitionParametersTerm = AcquisitionParameters
							.getInstance(cvManager)
							.getCVTermByAccession(
									new Accession(
											AcquisitionParameters.ACQUISITION_PARAMETER_ACCESSION));
					// List<Object> params =
					// prideCvUtil.getParamTypesFromString(
					// acquisitionParameters, cvManager,
					// acquisitionParametersTerm,
					// SEPOntologyRootTerm.getInstance(cvManager),
					// PSIMSOntologyRootTerm.getInstance(cvManager));
					// for (Object paramType : params) {
					// prideAdditional.getCvParamOrUserParam().add(paramType);
					// }
					prideCvUtil.addCvParamToParamType(prideAdditional,
							acquisitionParametersTerm.getTermAccession(),
							acquisitionParametersTerm.getPreferredName(),
							acquisitionParameters,
							acquisitionParametersTerm.getCVRef());
				}
				// parameters file
				String parametersFile = acquisition.getParameterFile();
				if (parametersFile != null && !"".equals(parametersFile)) {
					ControlVocabularyTerm parameterFileTerm = MSFileType
							.getInstance(cvManager).getCVTermByAccession(
									MSFileType.PARAMETER_FILE_CV);
					prideCvUtil.addCvParamOrUserParamToParamType(
							prideAdditional,
							parameterFileTerm.getPreferredName(),
							parametersFile, MSFileType.getInstance(cvManager));
				}
				// version
				String version = acquisition.getVersion();
				if (version != null && !"".equals(version))
					prideCvUtil.addUserParamToParamType(prideAdditional,
							"acquisition software version", version);
				// manufacturer
				String manufacturer = acquisition.getManufacturer();
				if (manufacturer != null && !"".equals(manufacturer)) {
					Accession accession = cvManager.getControlVocabularyId(
							manufacturer,
							SoftwareManufacturer.getInstance(cvManager));
					if (accession != null) {
						prideCvUtil.addCvParamOrUserParamToParamType(
								prideAdditional, manufacturer, null,
								SoftwareManufacturer.getInstance(cvManager));
					} else {
						prideCvUtil.addUserParamToParamType(prideAdditional,
								"aquisition software manufacturer",
								manufacturer);
					}

				}
				// role
				String role = acquisition.getDescription();
				if (role != null && !"".equals(role))
					prideCvUtil.addUserParamToParamType(prideAdditional,
							"acquisition software role", role);

				// target list
				String targetList = acquisition.getTargetList();
				if (targetList != null && !"".equals(targetList)) {
					final ControlVocabularyTerm targetListTerm = TargetList
							.getInstance(cvManager).getCVTermByAccession(
									new Accession(
											TargetList.TARGET_LIST_ACCESSION));
					prideCvUtil.addCvParamOrUserParamToParamType(
							prideAdditional, targetListTerm.getPreferredName(),
							targetList, TargetList.getInstance(cvManager));
				}
				// transitions file
				String transitionsFile = acquisition.getTransitionListFile();
				if (transitionsFile != null && !"".equals(transitionsFile))
					prideCvUtil
							.addUserParamToParamType(prideAdditional,
									"location of transition list file",
									transitionsFile);
			}

		} else {
			// create mandatory elements
			prideSource = createSource(null, null);
			prideAnalyzerList = createAnalyzers(null, null);
			// spectrometerName = "Unknown spectrometer";
			// UserParamType userParam = factory.createUserParamType();
			// userParam.setName("Detector");
			// userParam.setValue("Unknown");
			// prideDetectors.getCvParamOrUserParam().add(userParam);
		}

		// Mandatory
		prideInstrument.setInstrumentName(spectrometerName);
		prideInstrument.setSource(prideSource);
		prideInstrument.setAnalyzerList(prideAnalyzerList);
		prideInstrument.setDetector(prideDetectors);

		// not mandatory
		if (!prideAdditional.getCvParamOrUserParam().isEmpty())
			prideInstrument.setAdditional(prideAdditional);

		return prideInstrument;
	}

	private ParamType createSource(List<Esi> esis, List<Maldi> maldis) {
		log.info("CreateSource");
		ParamType paramType = factory.createParamType();

		if (esis != null && !esis.isEmpty()) {
			for (Esi esi : esis) {
				// ESI NAME
				String name = esi.getName();
				String value = "";
				if (name.contains("=")) {
					String[] tmp = name.split("=");
					name = tmp[0];
					value = tmp[1];
				}
				if (IonSourceName.isMaldiFromDescription(name, cvManager) == false) {
					ControlVocabularyTerm cvTerm = IonSourceName.getInstance(
							cvManager).getCVTermByPreferredName(name);
					if (cvTerm != null) {
						prideCvUtil.addCvParamToParamType(paramType,
								cvTerm.getTermAccession(),
								cvTerm.getPreferredName(), null,
								PSIMassSpectrometryOntology.getCVLabel());
					} else {
						if (!"".equals(value))
							prideCvUtil
									.addUserParamToParamType(
											paramType,
											IonSourceName.ELECTROSPRAY_IONIZATION,
											name);
						else
							prideCvUtil.addUserParamToParamType(paramType,
									name, value);
					}
				} else {
					if (!"".equals(value))
						prideCvUtil.addUserParamToParamType(paramType,
								IonSourceName.ELECTROSPRAY_IONIZATION, name);
					else
						prideCvUtil.addUserParamToParamType(paramType, name,
								value);
				}
				// Supply type
				String supplyType = esi.getSupplyType();
				if (supplyType != null && !"".equals(supplyType)) {
					prideCvUtil
							.addCvParamOrUserParamToParamType(paramType,
									supplyType, null,
									SupplyType.getInstance(cvManager));
				}
				// parameters
				String parameters = esi.getParameters();
				if (parameters != null && !"".equals(parameters)) {
					// List<Object> paramTypesFromString = prideCvUtil
					// .getParamTypesFromString(parameters, cvManager,
					// null, PSIMSOntologyRootTerm
					// .getInstance(cvManager),
					// SEPOntologyRootTerm.getInstance(cvManager));
					// for (Object object : paramTypesFromString) {
					// paramType.getCvParamOrUserParam().add(object);
					// }
					prideCvUtil.addCvParamOrUserParamToParamType(paramType,
							"source attribute", parameters);
				}
				// Interfaces
				Set<Equipment> interfaces = esi.getInterfaces();
				if (interfaces != null) {
					for (Equipment equipment : interfaces) {
						if (equipment != null) {
							// Name
							String sourceInterfaceName = equipment.getName();
							if (sourceInterfaceName != null
									&& !"".equals(sourceInterfaceName)) {
								ControlVocabularyTerm sourceInterfaceTerm = SourceInterface
										.getInstance(cvManager)
										.getCVTermByAccession(
												new Accession(
														SourceInterface.SOURCE_INTERFACE_ACCESSION));
								prideCvUtil
										.addCvParamToParamType(
												paramType,
												new Accession(
														SourceInterface.SOURCE_INTERFACE_ACCESSION),
												sourceInterfaceTerm
														.getPreferredName(),
												sourceInterfaceName,
												sourceInterfaceTerm.getCVRef());

							}
							// Description
							String sourceInterfaceDescription = equipment
									.getDescription();
							if (sourceInterfaceDescription != null
									&& !"".equals(sourceInterfaceDescription)) {
								prideCvUtil.addUserParamToParamType(paramType,
										"source interface description",
										sourceInterfaceDescription);

							}
							// model
							String sourceInterfaceModel = equipment.getModel();
							if (sourceInterfaceModel != null
									&& !"".equals(sourceInterfaceModel)) {
								ControlVocabularyTerm sourceInterfaceModelTerm = SourceInterface
										.getInstance(cvManager)
										.getCVTermByAccession(
												new Accession(
														SourceInterface.SOURCE_INTERFACE_MODEL_ACCESSION));
								prideCvUtil
										.addCvParamToParamType(
												paramType,
												new Accession(
														SourceInterface.SOURCE_INTERFACE_MODEL_ACCESSION),
												sourceInterfaceModelTerm
														.getPreferredName(),
												sourceInterfaceModel,
												sourceInterfaceModelTerm
														.getCVRef());

							}
							// manufacturer
							String sourceInterfaceManufacturer = equipment
									.getManufacturer();
							if (sourceInterfaceManufacturer != null
									&& !"".equals(sourceInterfaceManufacturer)) {
								ControlVocabularyTerm sourceInterfaceManufacturerTerm = SourceInterface
										.getInstance(cvManager)
										.getCVTermByAccession(
												new Accession(
														SourceInterface.SOURCE_INTERFACE_MANUFACTURER_ACCESSION));
								prideCvUtil
										.addCvParamToParamType(
												paramType,
												new Accession(
														SourceInterface.SOURCE_INTERFACE_MANUFACTURER_ACCESSION),
												sourceInterfaceManufacturerTerm
														.getPreferredName(),
												sourceInterfaceManufacturer,
												sourceInterfaceManufacturerTerm
														.getCVRef());

							}
						}
					}
				}
				// Sprayers
				Set<Equipment> sprayers = esi.getSprayers();
				if (sprayers != null) {
					for (Equipment equipment : sprayers) {
						if (equipment != null) {
							// Name
							String sourceSprayerName = equipment.getName();
							if (sourceSprayerName != null
									&& !"".equals(sourceSprayerName)) {
								ControlVocabularyTerm sourceSprayerTerm = SourceSprayer
										.getInstance(cvManager)
										.getCVTermByAccession(
												new Accession(
														SourceSprayer.SOURCE_SPRAYER_ACCESSION));
								prideCvUtil
										.addCvParamToParamType(
												paramType,
												new Accession(
														SourceSprayer.SOURCE_SPRAYER_ACCESSION),
												sourceSprayerTerm
														.getPreferredName(),
												sourceSprayerName,
												sourceSprayerTerm.getCVRef());

							}
							// type
							// TODO check if getDescription is equivalent to the
							// type
							String sourceSprayerDescription = equipment
									.getDescription();
							if (sourceSprayerDescription != null
									&& !"".equals(sourceSprayerDescription)) {
								ControlVocabularyTerm sourceSprayerModelTerm = SourceSprayer
										.getInstance(cvManager)
										.getCVTermByAccession(
												new Accession(
														SourceSprayer.SOURCE_SPRAYER_TYPE_ACCESSION));
								prideCvUtil
										.addCvParamToParamType(
												paramType,
												new Accession(
														SourceSprayer.SOURCE_SPRAYER_TYPE_ACCESSION),
												sourceSprayerModelTerm
														.getPreferredName(),
												sourceSprayerDescription,
												sourceSprayerModelTerm
														.getCVRef());

							}
							// model
							String sourceSprayerModel = equipment.getModel();
							if (sourceSprayerModel != null
									&& !"".equals(sourceSprayerModel)) {
								ControlVocabularyTerm sourceSprayerModelTerm = SourceSprayer
										.getInstance(cvManager)
										.getCVTermByAccession(
												new Accession(
														SourceSprayer.SOURCE_SPRAYER_MODEL_ACCESSION));
								prideCvUtil
										.addCvParamToParamType(
												paramType,
												new Accession(
														SourceSprayer.SOURCE_SPRAYER_MODEL_ACCESSION),
												sourceSprayerModelTerm
														.getPreferredName(),
												sourceSprayerModel,
												sourceSprayerModelTerm
														.getCVRef());

							}
							// manufacturer
							String sourceSprayerManufacturer = equipment
									.getManufacturer();
							if (sourceSprayerManufacturer != null
									&& !"".equals(sourceSprayerManufacturer)) {
								ControlVocabularyTerm sourceSprayerManufacturerTerm = SourceSprayer
										.getInstance(cvManager)
										.getCVTermByAccession(
												new Accession(
														SourceSprayer.SOURCE_SPRAYER_MANUFACTURER_ACCESSION));
								prideCvUtil
										.addCvParamToParamType(
												paramType,
												new Accession(
														SourceSprayer.SOURCE_SPRAYER_MANUFACTURER_ACCESSION),
												sourceSprayerManufacturerTerm
														.getPreferredName(),
												sourceSprayerManufacturer,
												sourceSprayerManufacturerTerm
														.getCVRef());

							}
						}
					}
				}
			}
		}
		if (maldis != null && !maldis.isEmpty()) {
			for (Maldi maldi : maldis) {
				// name
				String name = maldi.getName();
				String value = "";
				if (name.contains("=")) {
					String[] tmp = name.split(".");
					name = tmp[0];
					value = tmp[1];
				}
				if (IonSourceName.isMaldiFromDescription(name, cvManager)) {
					ControlVocabularyTerm cvTerm = IonSourceName.getInstance(
							cvManager).getCVTermByPreferredName(name);
					if (cvTerm != null) {
						prideCvUtil.addCvParamToParamType(paramType,
								cvTerm.getTermAccession(),
								cvTerm.getPreferredName(), null,
								PSIMassSpectrometryOntology.getCVLabel());
					} else {
						if (!"".equals(value))
							prideCvUtil
									.addUserParamToParamType(
											paramType,
											IonSourceName.MATRIX_ASSISTED_LASER_DESORPTION_IONIZATION,
											name);
						else
							prideCvUtil.addUserParamToParamType(paramType,
									name, value);
					}
				} else {
					if (!"".equals(value))
						prideCvUtil
								.addUserParamToParamType(
										paramType,
										IonSourceName.MATRIX_ASSISTED_LASER_DESORPTION_IONIZATION,
										name);
					else
						prideCvUtil.addUserParamToParamType(paramType, name,
								value);
				}
				// plate composition
				String plateComposition = maldi.getPlateType();
				if (plateComposition != null && !"".equals(plateComposition)) {
					prideCvUtil.addCvParamOrUserParamToParamType(paramType,
							plateComposition, null,
							SamplePlateType.getInstance(cvManager));
				}
				// Matrix composition
				String matrixComposition = maldi.getMatrix();
				if (matrixComposition != null && !"".equals(matrixComposition)) {
					prideCvUtil.addCvParamOrUserParamToParamType(paramType,
							matrixComposition, null,
							MatrixComposition.getInstance(cvManager));
				}
				// dissociation
				String dissociation = maldi.getDissociation();
				if (dissociation != null && !"".equals(dissociation)) {
					prideCvUtil.addCvParamOrUserParamToParamType(paramType,
							dissociation, null,
							MaldiDissociationMethod.getInstance(cvManager));
				}
				// dissociation description
				String dissociationDesc = maldi.getDissociationSummary();
				if (dissociationDesc != null && !"".equals(dissociationDesc)) {
					prideCvUtil.addCvParamOrUserParamToParamType(paramType,
							dissociationDesc, null,
							DissociationMethod.getInstance(cvManager));
				}
				// delayed extraction
				String delayedExtraction = maldi.getExtraction();
				if (delayedExtraction != null && !"".equals(delayedExtraction)) {
					ControlVocabularyTerm delayedExtractionTerm = DelayedExtraction
							.getInstance(cvManager)
							.getCVTermByAccession(
									new Accession(
											DelayedExtraction.DELAYED_EXTRACTION_ACCESSION));
					prideCvUtil.addCvParamOrUserParamToParamType(paramType,
							delayedExtractionTerm.getPreferredName(),
							delayedExtraction,
							DelayedExtraction.getInstance(cvManager));
				}
				// laser type
				String laserType = maldi.getLaser();
				if (laserType != null && !"".equals(laserType)) {
					prideCvUtil.addCvParamOrUserParamToParamType(paramType,
							laserType, null, LaserType.getInstance(cvManager));
				}
				// laser wavelenght
				String laserWaveLength = maldi.getLaserWaveLength();
				if (laserWaveLength != null && !"".equals(laserWaveLength)) {
					ControlVocabularyTerm laserWavelenghtTerm = LaserAttribute
							.getInstance(cvManager).getCVTermByAccession(
									new Accession(
											LaserAttribute.LASER_WAVELENGTH));
					prideCvUtil.addCvParamOrUserParamToParamType(paramType,
							laserWavelenghtTerm.getPreferredName(),
							laserWaveLength,
							LaserAttribute.getInstance(cvManager));
				}
				// other laser parameters
				String laserParameters = maldi.getLaserParameters();
				if (laserParameters != null && !"".equals(laserParameters)) {
					ControlVocabularyTerm laserAttributeTerm = LaserAttribute
							.getInstance(cvManager).getCVTermByAccession(
									new Accession(
											LaserAttribute.LASER_ATTRIBUTE));
					prideCvUtil.addCvParamOrUserParamToParamType(paramType,
							laserAttributeTerm.getPreferredName(),
							laserParameters,
							LaserAttribute.getInstance(cvManager));
				}
			}
		}
		return paramType;
	}

	private AnalyzerList createAnalyzers(List<Analyser> analyzers,
			Set<ActivationDissociation> activationDissociations) {
		ParamType analyzerParamType;
		log.info("CreateAnalyzers");
		AnalyzerList prideAnalyzerList = factory
				.createInstrumentDescriptionTypeAnalyzerList();
		boolean ionOpticsProcessed = false;
		boolean activationDissociationsProcessed = false;

		if (analyzers != null && !analyzers.isEmpty()) {
			for (Analyser analyzer : analyzers) {
				// parse analyzer from MIAPE MS
				analyzerParamType = factory.createParamType();
				String name = analyzer.getName();
				String description = analyzer.getDescription();
				String value = null;
				if (name != null) {
					if (name.contains("=")) {
						String[] tmp = name.split("=");
						name = tmp[0];
						value = tmp[1];
					}

					Accession cvId = cvManager.getControlVocabularyId(name,
							MassAnalyzerType.getInstance(cvManager));
					if (cvId != null) {
						prideCvUtil.addCvParamOrUserParamToParamType(
								analyzerParamType, name, null,
								MassAnalyzerType.getInstance(cvManager));
					} else {
						ControlVocabularyTerm cvTerm = MassAnalyzerType
								.getInstance(cvManager)
								.getCVTermByAccession(
										MassAnalyzerType.MASS_ANALYZER_TYPE_ACCESSION);
						if (value != null) {
							prideCvUtil.addUserParamToParamType(
									analyzerParamType, name, value);
						} else {
							prideCvUtil.addCvParamToParamType(
									analyzerParamType,
									cvTerm.getTermAccession(),
									cvTerm.getPreferredName(), name,
									cvTerm.getCVRef());
						}
					}
				}
				final String reflectron = analyzer.getReflectron();
				if (reflectron != null) {
					Accession cvId = cvManager.getControlVocabularyId(
							reflectron, ReflectronState.getInstance(cvManager));
					if (cvId != null) {
						String cvRef = cvManager.getCVRef(cvId,
								ReflectronState.getInstance(cvManager));
						String refDesc = cvManager.getControlVocabularyName(
								cvId, ReflectronState.getInstance(cvManager));
						prideCvUtil.addCvParamToParamType(analyzerParamType,
								cvId, reflectron, refDesc, cvRef);
					} else {
						ControlVocabularyTerm cvTerm = ReflectronState
								.getInstance(cvManager)
								.getCVTermByAccession(
										ReflectronState.REFLECTRON_STATE_ACCESSION);
						prideCvUtil.addCvParamToParamType(analyzerParamType,
								cvTerm.getTermAccession(),
								cvTerm.getPreferredName(), reflectron,
								cvTerm.getCVRef());
					}
				}
				if (description != null) {
					final UserParamType userParam = prideCvUtil
							.createUserParam("analyzer description",
									description);
					analyzerParamType.getCvParamOrUserParam().add(userParam);
				}

				// parse ionOptics from MIAPE MS only if it is the first time
				// if (!ionOpticsProcessed) {
				// if (ionOptics != null && !ionOptics.isEmpty()) {
				// for (IonOptic ionOptic : ionOptics) {
				// String ionOpticName = ionOptic.getName();
				// if (ionOpticName != null) {
				// Accession cvId =
				// cvManager.getControlVocabularyId(ionOpticName,
				// IonOpticsType.getInstance(cvManager));
				// if (cvId != null) {
				// String cvRef = cvManager.getCVRef(cvId,
				// IonOpticsType.getInstance(cvManager));
				// String description = cvManager.getControlVocabularyName(cvId,
				// IonOpticsType.getInstance(cvManager));
				// prideCvUtil.addCvParamToParamType(analyzerParamType, cvId,
				// ionOpticName, description, cvRef);
				// } else {
				// prideCvUtil.addUserParamToParamType(analyzerParamType,
				// PrideControlVocabularyXmlFactory.ION_OPTICS,
				// ionOpticName);
				// }
				// }
				// ionOpticsProcessed = true;
				// }
				// }
				// }

				if (!activationDissociationsProcessed) {
					// Collision cells
					if (activationDissociations != null
							&& !activationDissociations.isEmpty()) {
						for (ActivationDissociation collisionCell : activationDissociations) {
							if (analyzerParamType == null)
								analyzerParamType = factory.createParamType();
							String collisionCellName = collisionCell.getName();
							// Name
							if (collisionCellName != null) {
								prideCvUtil
										.addUserParamToParamType(
												analyzerParamType,
												PrideControlVocabularyXmlFactory.ACTIVATION_DISSOCIATION_COMPONENT,
												collisionCellName);
							}
							// Activation type
							final String activationType = collisionCell
									.getActivationType();
							if (activationType != null) {
								ControlVocabularyTerm cvTerm = DissociationMethod
										.getInstance(cvManager)
										.getCVTermByAccession(
												DissociationMethod.DISSOCIATION_METHOD_ACCESSION);
								prideCvUtil.addCvParamToParamType(
										analyzerParamType,
										cvTerm.getTermAccession(),
										cvTerm.getPreferredName(),
										activationType, cvTerm.getCVRef());
							}

							// Gas type
							final String gasType = collisionCell.getGasType();
							if (gasType != null) {
								ControlVocabularyTerm cvTerm = GasType
										.getInstance(cvManager)
										.getCVTermByAccession(
												GasType.COLLISION_GAS);
								prideCvUtil.addCvParamToParamType(
										analyzerParamType,
										cvTerm.getTermAccession(),
										cvTerm.getPreferredName(), gasType,
										cvTerm.getCVRef());
							}
							// Gas pressure
							final String gasPressure = collisionCell
									.getGasPressure();
							if (gasPressure != null) {
								ControlVocabularyTerm collissionPressureCVTerm = CollisionPressure
										.getCollisionPressureTerm();
								if (collissionPressureCVTerm != null)
									prideCvUtil
											.addCvParamToParamType(
													analyzerParamType,
													collissionPressureCVTerm
															.getTermAccession(),
													collissionPressureCVTerm
															.getPreferredName(),
													gasPressure,
													collissionPressureCVTerm
															.getCVRef());
							}
							// Gas pressure units
							final String gasPressureUnits = collisionCell
									.getPressureUnit();
							if (gasPressureUnits != null) {
								prideCvUtil
										.addUserParamToParamType(
												analyzerParamType,
												PrideControlVocabularyXmlFactory.GAS_PRESSURE_UNIT,
												gasPressureUnits);
							}

						}
						activationDissociationsProcessed = true;
					}
				}
				if (!analyzerParamType.getCvParamOrUserParam().isEmpty()) {
					prideAnalyzerList.getAnalyzer().add(analyzerParamType);
				}
				// end analyzer loop
			}

		}

		// It is mandatory to have the Analyzer element
		if (prideAnalyzerList.getAnalyzer().isEmpty()) {
			analyzerParamType = factory.createParamType();
			log.info("There is not analyzers in MIAPE MS");
			prideCvUtil.addUserParamToParamType(analyzerParamType,
					"unknown analyzer", null);
			prideAnalyzerList.getAnalyzer().add(analyzerParamType);
		}

		prideAnalyzerList.setCount(prideAnalyzerList.getAnalyzer().size());
		return prideAnalyzerList;
	}

}
